package org.dna.metronomo.persistence.impl;

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.logging.Logger;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.dna.metronomo.persistence.DBInit;
import org.dna.metronomo.persistence.PersistenceException;
import org.tigris.scarab.mapper.ActivityMapper;

class IBatisMetronomoDAO {

    static final String STATUS_DELETED = "DELETED";

    static interface SessionExecutor<T> {

        T execute(SqlSession session) throws SQLException;
    }
    static final String CONF_PATH = "org/dna/metronomo/persistence/configuration.xml";
    private static final Logger LOG = Logger.getLogger("org.dna.metronomo.persistence");
    SqlSessionFactory m_sqlSessionFactory;

    protected IBatisMetronomoDAO() throws PersistenceException {
        Reader reader;
        try {
            reader = Resources.getResourceAsReader(CONF_PATH);
        } catch (IOException e) {
            LOG.throwing(getClass().getName(), "Constructor", e);
            throw new PersistenceException(e);
        }
        m_sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

        //Explicit registration because the namespace in the xml doesnt' contain
        //the fully qualified classname of the mapper.
//        m_sqlSessionFactory.getConfiguration().addMapper(ActivityMapper.class);
//        m_sqlSessionFactory.getConfiguration().addMapper(UserMapper.class);
    }

    /**
     * This is the schema configuration utility.
     *
     * Note that this is automatically configured to run on startup as a spring
     * bean "init-method"
     */
    public synchronized void createSchema() throws PersistenceException {
        DBInit.createSchema();
    }

    protected final <T> T executeInSession(SessionExecutor<T> exec) {
        SqlSession session = m_sqlSessionFactory.openSession();
        T res;
        try {
            res = exec.execute(session);
            session.commit();
        } catch (Exception e) {
            throw new PersistenceException(e);
        } finally {
            session.close();
        }
        return res;
    }
}
